package com.ruoyi.monitor.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.monitor.Vo.JobVo;
import com.ruoyi.monitor.Vo.MsgCountVo;
import com.ruoyi.monitor.domain.AutoSendTask;
import com.ruoyi.monitor.domain.SysMsg;
import com.ruoyi.monitor.service.IAutoSendTaskService;
import com.ruoyi.monitor.service.ISysMsgService;
import com.ruoyi.monitor.utils.Email.Mail;
import com.ruoyi.monitor.utils.Email.MailCenter;
import com.ruoyi.monitor.utils.Msg.Message;
import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.quartz.util.CronUtils;
import com.ruoyi.system.service.ISysUserService;
import org.quartz.SchedulerException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;


@RestController
@RequestMapping("/monitor/sender")
public class SenderController extends BaseController {

    @Autowired
    private ISysMsgService msgService;
    @Autowired
    @Qualifier("threadPoolTaskExecutor")
    ThreadPoolTaskExecutor pool;
    @Autowired
    private IAutoSendTaskService sendTaskService;
    @Autowired
    private ISysJobService jobService;
    @Autowired
    MailCenter mailCenter;
    @Autowired
    private ISysUserService userService;


    /***
     * 统计预警次数 按照rank uuid+areacode统计
     * @return
     */

    @GetMapping("/countAlarm/{type}")
    public AjaxResult countAlarm(@PathVariable String type){
        List<MsgCountVo> msgCountVos = msgService.countAlarm(type);
        return success(msgCountVos);
    }


    @GetMapping("/countRunning")
    public AjaxResult countRunning(){
        int runningJobs = jobService.countRunningJobs();
        System.out.println("现在有多少任务在运行"+runningJobs);
        return success(runningJobs);
    }
    /**
     * 完全删除定时任务
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
    @Log(title = "定时任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/delete/{jobIds}")
    public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
    {
        List<Long> ids = Arrays.asList(jobIds);
        pool.submit(()->{
            ids.forEach(id->{
                sendTaskService.deleteAutoSendTaskByJobId(id);
            });
        });
        jobService.deleteJobByIds(jobIds);
        return success();
    }

    /**
     * 查询有uuid的定时任务列表
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
    @GetMapping("/listByUUID")
    public TableDataInfo listByUUID(SysJob sysJob)
    {
        startPage();
        List<SysJob> list = jobService.selectJobListUUID(sysJob);
        List<JobVo> jobVoList = new ArrayList<>();
        list.forEach(job -> {
            JobVo jobVo = new JobVo();
            BeanUtils.copyProperties(job,jobVo);
            Long jobId = job.getJobId();
            List<AutoSendTask> tasks = sendTaskService.selectTasksByJobId(jobId);
            tasks.forEach(task->{
                SysUser user = userService.selectUserById(task.getUserId());
                task.setUser(user);
            });
            jobVo.setTasks(tasks);
            jobVoList.add(jobVo);
        });
//        System.out.println(jobVoList);
        return getDataTable(jobVoList);
    }

    /**
     * 自动发送，定时任务,先插入，再获取id，把id传入方法
     *
     * 优化方案：直接传入uuid，任务表通过uuid绑定定时任务
     */
    @PostMapping("/autoSend/add")
    public AjaxResult autoSendAdd(@RequestBody JobVo jobVo){
        int result = -1;
        System.out.println(jobVo);
        if (!CronUtils.isValid(jobVo.getCronExpression()))
        {
            return error("新增任务'" + jobVo.getJobName() + "'失败，Cron表达式不正确");
        }
        SysJob job = new SysJob();
        BeanUtils.copyProperties(jobVo,job);
        Date create = new Date();
        job.setCreateBy(getUsername());
        if("\'null\'".equals(job.getJobGroup())){
            job.setJobGroup("DEFAULT");
        }
        if ("\'null\'".equals(job.getMisfirePolicy())){
            job.setMisfirePolicy("1");
        }
        if ("\'null\'".equals(job.getConcurrent())){
            job.setConcurrent("1");
        }
        if ("\'null\'".equals(job.getStatus())){
            job.setStatus("0");
        }
        String uuid = UUID.randomUUID().toString();
        job.setUuid(uuid);

        int onlyJob = jobService.insertOnlyJob(job);
        if (onlyJob!=0){
        SysJob sysJob = jobService.selectByUUID(uuid);
//        System.out.println(sysJob);
            List<Long> userIds = Arrays.asList(jobVo.getUserIds());
            userIds.forEach(id->{
                AutoSendTask task = new AutoSendTask();
                task.setJobId(sysJob.getJobId());
                task.setContent(jobVo.getMsg().getContent());
                task.setTitle(jobVo.getMsg().getTitle());
                task.setModelId(jobVo.getMsg().getModelId());
                task.setUserId(id);
                sendTaskService.insertAutoSendTask(task);

            });
            sysJob.setCreateTime(create);
            sysJob.setInvokeTarget("sender.sendTo("+sysJob.getJobId()+")");
            System.out.println(sysJob);
            try {
                result = jobService.updateJob(sysJob);
            } catch (SchedulerException e) {
                e.printStackTrace();
            } catch (TaskException e) {
                e.printStackTrace();
            }

        }
        if (result!=-1){
            return success(result);
        }else {
            return error();
        }
    }

    /**
     * 批量发送
     */
    @PreAuthorize("@ss.hasPermi('monitor:sender:sendBatch')")
    @PostMapping("/sendBatch/{ids}")
    public AjaxResult sendToUsers(@PathVariable Long[] ids,@RequestBody SysMsg msg)
    {
        List<SysMsg> sysMsgs = new ArrayList<>();
            if (!ObjectUtils.isEmpty(ids)) {
                    List<SysUser> sysUsers = userService.selectUsersByIds(ids);
                    sysUsers.forEach(user -> {
                    msg.setUserId(user.getUserId());
                    msg.setDate(new Date());
                    pool.submit(()-> {
                        mailCenter.sendTo(user, msg);
                    });
                    System.out.println("-----------批量发送内容-----------");
                    System.out.println(msg);
                    System.out.println("--------------------------");
                    sysMsgs.add(msg);
                });
            }
        return success(msgService.saveBatch(sysMsgs));
    }

    /**
     * 单个发送
     */
    @PreAuthorize("@ss.hasPermi('monitor:sender:send')")
    @PostMapping("/send")
    public AjaxResult sendToUser(@RequestBody SysMsg msg)
    {
        msg.setDate(new Date());
//        msg.setRank("通知");
        pool.submit(()->{
            SysUser user = userService.selectUserById(msg.getUserId());
            mailCenter.sendTo(user,msg);
        });
        System.out.println("-----------发送内容-----------");
        System.out.println(msg);
        System.out.println("--------------------------");
        return success(msgService.save(msg));
    }




    /**
     * 统计总发送数据
     */
    @PreAuthorize("@ss.hasPermi('monitor:sender:count')")
    @GetMapping("/countAll")
    public AjaxResult count()
    {
        HashMap<String,Long> map = new HashMap<>();
        long count = msgService.count(new LambdaQueryWrapper<SysMsg>()
                .eq(SysMsg::getType, Mail.TYPE_EMAIL));
        long count1 = msgService.count(new LambdaQueryWrapper<SysMsg>()
                .eq(SysMsg::getType, Message.TYPE_MESSAGE));;
        map.put("mailCount",count);
        map.put("msgCount",count1);
        System.out.println("发送数据收集"+map);
        return success(map);
    }

    /**
     * 折线图本月和上月
     */
    @PreAuthorize("@ss.hasPermi('sender:count')")
    @GetMapping("/count/type/{type}")
    public TableDataInfo lineChartDefault(@PathVariable("type")String type)
    {
        List<MsgCountVo> msgCountVos = msgService.countMsgs(type);
        return getDataTable(msgCountVos);
    }

    /**
     * 折线图自定义
     */
    @PreAuthorize("@ss.hasPermi('sender:count')")
    @GetMapping("/count/date/{dates}")
    public TableDataInfo lineChart(@PathVariable("dates")Date[] dates)
    {
        List<MsgCountVo> msgCountVos = msgService.countMsgsFromTo(dates[0], dates[1]);
        return getDataTable(msgCountVos);
    }
}
